package;
import Editor;
import Menu;
import MenuItem;
import View;
import GlobalSettings;
import haxe.Serializer;
import haxe.Unserializer;

//This class will create a haxe menu in notepad++
extern class MenuCmds{}
class Hxnpp
{
	static var haxePluginDir:String=Editor.nppDir+"\\plugins\\haxe";
	var menuHaxe:Menu;
	var menuApi:Menu;
	var menuBuildHistory:Menu;
	var settingsMenu: Menu;
	var projectMenu:Menu;
	var itemCurrentBuild:Menu;
	var itemDisableHaxeContext:MenuItem; 
	var buildHistoryItems:Array<MenuItem>;
	var buildHistory:Array< { dir:String, file:String, options:Int, project:Array<String> } >;
	var lastLength:Int;
	static var haxeContextDisabled:Bool=false;
	static var eval:String->Void;
	public function new()
	{
		lastLength=0;
		eval = untyped __js__("eval");
		var fso = untyped __js__("new ActiveXObject(\"Scripting.FileSystemObject\")");
		var fh = fso.OpenTextFile(haxePluginDir+"\\haxeplugindir.txt", 2, true);
		fh.Write('"'+haxePluginDir+'"');
		fh.Close();
		
		buildHistory = Unserializer.run(GlobalSettings.get('buildHistory'));
		menuHaxe = Editor.addMenu("haXe");
		itemCurrentBuild = Editor.addMenu("");
		setCurrentBuildPathMenu(buildHistory.length>0?buildHistory[0]:null);
		
		addBuildFileItem();
		
		buildHistoryItems=new Array();
		menuBuildHistory = menuHaxe.addMenu("Build history");
		updateBuildFileHistory();
		var itemClear = menuHaxe.addItem({text:"Clear build history",ctrl:false,shift:false,alt:false,key:"",cmd:clearBuildHistory,checked:false,disabled:false});
		
		//settingsMenu = menuHaxe.addMenu("Settings");
		//addSettingsMenu();
		projectMenu = menuHaxe.addMenu("Session");
		addProjectMenu();
		
		addPathSettingMenu(); 
		
		menuHaxe.addSeparator();
		menuApi = menuHaxe.addMenu("http://haxe.org/api");
		addApiItems();
		addOtherLinks();
		
		addRunMenu();
	}
	function addProjectMenu()
	{
		//var sessionOptionsMenu = projectMenu.addMenu("Session");
		projectMenu.addItem({text:"Save session",ctrl:false,shift:false,alt:false,key:"",cmd:saveSession,checked:false,disabled:false});
		projectMenu.addItem({text:"Open session",ctrl:false,shift:false,alt:false,key:"",cmd:openSession,checked:false,disabled:false});
		projectMenu.addItem({text:"Close session",ctrl:false,shift:false,alt:false,key:"",cmd:closeSession,checked:false,disabled:false});
		projectMenu.addItem({text:"Clear session",ctrl:false,shift:false,alt:false,key:"",cmd:clearSession,checked:false,disabled:false});

	}
	function saveSession()
	{
		buildHistory[0].project = Editor.currentView.files;
		GlobalSettings.set("buildHistory", Serializer.run(buildHistory));
		//for(f in buildHistory[0].project)
			//Editor.alert(f);
	}
	function clearSession()
	{
		buildHistory[0].project = new Array();
		GlobalSettings.set("buildHistory", Serializer.run(buildHistory));
		//for(f in buildHistory[0].project)
			//Editor.alert(f);
	}
	function openSession()
	{
		var files:Array<String> = buildHistory[0].project;
		for(f in files)
		{
			//Editor.alert(f);
			Editor.open(f);
		}
	}
	function closeSession()
	{
		var files:Array<String> = buildHistory[0].project;
		for(f in files)
		{
			//Editor.alert(f);
			Editor.open(f);
			untyped __js__("MenuCmds.FILE_CLOSE")();
			//Editor.runMenuCmd(4103);
			//Editor.FILE_CLOSE()
		}
	}
	function addRunMenu()
	{
		var runMenu = menuHaxe.addMenu("Run");
		runMenu.addItem({
			text:"Clipboard",
			ctrl:false,
			shift:false,
			alt:false,
			key:"",
			cmd: function(){
				eval(Editor.clipBoard);
			},checked:false,disabled:false
		});
		var rsel = {
			text:"Selection",
			ctrl:false,
			shift:false,
			alt:false,
			key:"",
			cmd: function(){
				eval(Editor.currentView.selection);
			},checked:false,disabled:false
		};
		runMenu.addItem(rsel);


		runMenu.addItem({
			text:"Current View",
			ctrl:false,
			shift:false,
			alt:false,
			key:"",
			cmd: function(){
				eval(Editor.currentView.text);
			},checked:false,disabled:false
		});
	}
	function addSettingsMenu()
	{
		//settings.disabled=true;
		itemDisableHaxeContext = settingsMenu.addItem({text:"Disable haXe context",ctrl:false,shift:false,alt:false,key:"",cmd:toggleHaxeContext,checked:false,disabled:false});
	}
	function addPathSettingMenu()
	{
		var setCurrentPathAppearance=setCurrentPathAppearance;
		var pathSetting = projectMenu.addMenu("Path appearance");
		pathSetting.addItem({text:"none", ctrl:false,shift:false,alt:false,key:"",cmd:function(){setCurrentPathAppearance(-1);},checked:false,disabled:false});
		pathSetting.addItem({text:"all", ctrl:false,shift:false,alt:false,key:"",cmd:function(){setCurrentPathAppearance(100);},checked:false,disabled:false});
		for(i in 1...10)
			pathSetting.addItem({text:Std.string((i)), ctrl:false,shift:false,alt:false,key:"",cmd:function(){setCurrentPathAppearance((i));},checked:false,disabled:false});
		//menuHaxe.addSeparator();
	}
	function setCurrentPathAppearance(total:Int)
	{
		buildHistory[0].options=total;
		GlobalSettings.set("buildHistory", Serializer.run(buildHistory));
		setCurrentBuildPathMenu(buildHistory[0]);
	}
	function setCurrentBuildPathMenu(hItem)
	{
		if(hItem == null)
		{
			itemCurrentBuild.text="|   No build file set.";
		}
		else if(hItem.options==-1)
		{
			itemCurrentBuild.text = "";
		}
		else
		{
			var parts:Array<String> = hItem.file.split('\\');
			var path ="|   ";
			var start:Int = parts.length - hItem.options;
			if(start<0)start=0;
			var idx:Int=start;
			var len=parts.length-start;
			for(i in 0...len)
			{
				path += ((i!=0)? '\\':"") +parts[idx];
				idx++;
			}
			itemCurrentBuild.text = path;
		}
	}
	public function addBuildFileItem():Void
	{
		var setBuildFile = this.setBuildFile;
		var itemHxbuild = menuHaxe.addItem({text:"Set current as build",ctrl:false,shift:false,alt:false,key:"",cmd:function()setBuildFile(Editor.currentView.files[Editor.currentView.file])/*setCurrentAsBuild */,checked:false,disabled:false});
		Editor.addSystemHotKey(itemHxbuild);
	}
	public function addApiItems():Void
	{	
		var apis:Array<{n:String, p:Array<String>}>=
		[
			{n:"cpp",p:["io", "net", "vm", "zip"]},
			{n:"flash",p:["display","external","filters","geom","net","system","text"]},
			{n:"flash9",p:["accessibility", "desktop", "display", "errors", "events", "external", "filters", "geom", "media", "net", "printing", "sample", "system", "text", "trace", "ui", "utils", "xml"]},
			{n:"haxe",p:["io", "remoting", "rtti", "unit", "xml"]},
			{n:"js",p:[]},
			{n:"neko",p:["db", "io", "net", "vm", "zip"]},
			{n:"php",p:["db", "io", "net"]},
			{n:"tools",p:["haxedoc", "haxelin", "hxinst"]}
		];
		menuApi.addItem({text : "api",ctrl:false,shift:false,alt:false,key:"",cmd:function()visitURL("http://haxe.org/api"),checked:false,disabled:false});
		menuApi.addSeparator();
		for(i in 0...apis.length)
		{
			var api = apis[i];
			var subMenu:Menu = menuApi.addMenu(api.n);
			subMenu.addItem({text : api.n,ctrl:false,shift:false,alt:false,key:"",cmd:function()visitURL("http://haxe.org/api/"+api.n),checked:false,disabled:false});
			subMenu.addSeparator();
			for(j in api.p)
				subMenu.addItem({text : j,ctrl:false,shift:false,alt:false,key:"",cmd:function()visitURL("http://haxe.org/api/"+api.n+"/"+j),checked:false,disabled:false});
		}
	}
	static function visitURL(url:String)
	{
		untyped __js__("new ActiveXObject(\"WScript.Shell\")").run(url);
	}
	function addOtherLinks():Void
	{
		menuHaxe.addItem({text:"mailing list",ctrl:false,shift:false,alt:false,key:"",cmd:function()visitURL("http://haxe.1354130.n2.nabble.com/"),checked:false,disabled:false});
		menuHaxe.addItem({text:"forum",ctrl:false,shift:false,alt:false,key:"",cmd:function()visitURL("http://haxe.org/forum"),checked:false,disabled:false});
		menuHaxe.addItem({text:"blogs",ctrl:false,shift:false,alt:false,key:"",cmd:function()visitURL("http://www.google.com/reader/shared/user/13356518299296258863/label/Share"),checked:false,disabled:false});
		menuHaxe.addItem({text:"issues",ctrl:false,shift:false,alt:false,key:"",cmd:function()visitURL("http://code.google.com/p/haxe/issues/list"),checked:false,disabled:false});
		menuHaxe.addItem({text:"download",ctrl:false,shift:false,alt:false,key:"",cmd:function()visitURL("http://haxe.org/download"),checked:false,disabled:false});
		//Editor.addSystemHotKey(itemBuildFile);
	}
	function setBuildFile(fileName:String)
	{
		if(fileName.indexOf(".hxml")==-1)
		{
			Editor.alert("Error!\n" + fileName + "\nmust be a .hxml file");
			return;
		}
		var folderNameParts:Array<String>=fileName.split("\\");
		folderNameParts.pop();
		var folderName = folderNameParts.join('\\');
		
		var fso = untyped __js__("new ActiveXObject(\"Scripting.FileSystemObject\")");
		var fh = fso.OpenTextFile(haxePluginDir+"\\currentBF.txt", 2, true);
		fh.Write('"'+fileName+'"');
		fh.Close();

		fh = fso.OpenTextFile(haxePluginDir + "\\currentBD.txt", 2, true);
		fh.Write('"'+folderName+'"');
		fh.Close();
		
		fh = fso.OpenTextFile(haxePluginDir + "\\currentBFP.txt", 2, true);
		fh.Write('"'+fileName.split("\\").pop()+'"');
		fh.Close();
		
		//itemCurrentBuild.text = fileName;
		var opt=-1;
		var proj:Array<String>=[];
		for(i in buildHistory)
			if(i.file == fileName)
				{
					opt = i.options;
					proj = i.project;
				}
		updateBuildHistory({ dir:folderName, file:fileName, options:opt, project:proj});
		//Editor.alert("hxbuild was set to:\n" + fileName);
	}
	public function updateBuildHistory(c)
	{
		var out:Array<{ dir:String, file:String, options:Int, project:Array<String> } > = [c];
		for(i in buildHistory)
			if(i.file != c.file)
				out.push(i);
		if(out.length>10)
			out.pop();
		buildHistory=new Array().concat(out);
		GlobalSettings.set("buildHistory",Serializer.run(buildHistory));
		setCurrentBuildPathMenu(c);
		updateBuildFileHistory();
	}
	public function updateBuildFileHistory()
	{
		var setBuildFile = this.setBuildFile;
		var index=0;
		for(i in buildHistory)
		{
			if(index<lastLength)
			{
				buildHistoryItems[index].text=i.file;
			}
			else
			{
				var item:MenuItem=null;
				item  = menuBuildHistory.addItem(
				{
					text : i.file,
					ctrl:false,
					shift:false,
					alt:false,
					key:"",
					cmd:function(){setBuildFile(item.text);},
					checked:false,
					disabled:false
				});
				buildHistoryItems.push(item);
			}
			if(index==0)
				buildHistoryItems[index].checked=true;
			index++;
		}
		lastLength=buildHistory.length;
	}
	public function clearBuildHistory()
	{
		var index=0;
		for(i in buildHistory)
		{
			buildHistoryItems[index].text="";
			index++;
		}
		buildHistory=new Array();
		GlobalSettings.set("buildHistory", Serializer.run(buildHistory));
		Editor.alert("History will be empty after restart.");
	}
	public function toggleHaxeContext()
	{
		//Editor.alert("toggleHaxeContext");
		itemDisableHaxeContext.checked = !itemDisableHaxeContext.checked;
		GlobalSettings.set("haxeContextDisabled",itemDisableHaxeContext.checked);
	}
	public static function main()
	{
		new Hxnpp();
	}
}